# @Time : 2024-10-19 16:09
# @Author : Fioman 
# @Phone : 13149920693
"""
Python中函数常见的参数传递方式研究
"""


# region 1. 参数传递方式 位置传参 | 关键字传参 | 混合传参 | 缺省参数
# 1) 位置传参 形参和实参按照对应位置,使用最多
def position_args_func(parm1, parm2, param3):
    print(f"parm1 : {parm1}, parm2 : {parm2}, param3 : {param3}")


args1, args2, args3 = [1, 2, 3]
position_args_func(args1, args2, args3)  # 普通位置传参
position_args_func(*[4, 5, 6])  # 序列传参,解包的方式去传参
tupArgs = ("我", "是", "谁")
position_args_func(*tupArgs)
position_args_func(*{"A": 1, "B": 2, "C": 3})  # 只会解包键
position_args_func(*range(1, 4))
position_args_func(*"你好呀")


# 2) 关键字传参
def keyword_args_func(param1, param2, param3):
    print(f"parm1: {param1}, parm2: {param2}, param3: {param3}")


# 赋值表达式关键字传参
keyword_args_func(param1=1, param2=2, param3=3)
keyword_args_func(param1="A", param2="B", param3="C")
# 字典传参(配合双星号),字典的键名和形参的名称要一致
dtArgs = {"param1": 1, "param2": 2, "param3": 3}
keyword_args_func(**dtArgs)
dtArgs = dict.fromkeys(["param1", "param2", "param3"], "我是默认值")
keyword_args_func(**dtArgs)


# 3) 位置传参和关键字传参的混合使用
def position_keyword_args_both_func(a, b, c, d):
    print(f"a : {a},b: {b},c: {c},d: {d}")


# 位置传参和关键字传参配合使用的时候,关键字没有顺序要求,但是个数和名称必须对应上
position_keyword_args_both_func("aa", c="CC", b="BB", d="DD")
# 但是不能关键字传参在前,位置传参在后面
# position_keyword_args_both_func(a="A", c="C", "BB", "DD")
# 位置传参和*号配合使用
position_keyword_args_both_func("aa", *["BB", "CC"], "DD")
# *号和**号配合使用
position_keyword_args_both_func(*[1, 2], **{"d": "CCCC", "c": "DDDDD"})
# *号和赋值表达式一起使用
position_keyword_args_both_func(*["a", "b"], d="Just", c="Abc")


# 4) 函数的缺省参数
# def func(param1,param2=val2,param3=val3) 这种方式进行定义的函数,表示带有缺省参数,
# 可以给func提供默认值val2,val3,在函数调用的时候如果没有提供,则会使用默认值
# 缺省参数必须是在位置参数的后面,并且如果一个参数是缺省参数,那么它后面的所有的参数都必须是缺省参数.
def default_args_function(a, b=0, c=1, d=2):
    print(f"a : {a},b: {b},c: {c},d: {d}")


default_args_function(1)
default_args_function(1, 2)
default_args_function(1, c=3)
# 缺省参数也可以使用位置传参,也可以使用关键字传参
default_args_function(1, 2, 3, 4)


# endregion


# region 2. 不定长参数定义 *args **kwargs
def func(*args):
    # args是一个元组
    print(f"args : {args}")


# 可以接收不定长的参数,包括长度为0
func()
func(1, 2, 3, [1, 2, 3])
func(1, 2, 3, *[1, 2, 3, 4, 5])


def func(**kwargs):
    # kwargs 是一个字典
    print(f"kwargs : {kwargs}")


func()
func(a=1, b=2, c=3)
# 注意这里必须先解包为关键字传参,因为如果不解包的话,相当于传过去一个字典
func(**{"a": 1, "b": 2, "c": 3})


# endregion

# region 3. * 号占位符,强制后面的参数必须是关键字传参
def star_placeholder_args_func(a, *, b, c):
    print(f"a : {a},b: {b},c: {c}")


# * 号后面的b和c必须是关键字传参,这样设计的目的是为了传参的时候,传递错误,使得传参准确性更高
star_placeholder_args_func(1, c=2, b=3)


# star_placeholder_args_func(1,2, c=3) 错误,后面必须是关键字传参
# endregion

# region 4. 混合使用  位置参数 => 默认缺省参数 => 型号元组参数 => 命名关键字 => 双星号字典传参
def complex_func(a, b, c="cc", d="dd", *args, e, f, **kwargs):
    print(a, b, c, d, e, f, args, kwargs)


complex_func(1, 2, "DDDD", "CCC", (5, 6), e=7, f=8, g="g", h='h')
# endregion
